﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Web;
using System.Security.Cryptography;
using System.Xml;

namespace Devfw.OpenAuth.Platform
{

    //开心网记录权限
    public enum KaixinRecordPrivacy
    {
        Public = 0,
        Friend = 1,
        Private = 2

    }

    //人人网相册类型(自己和所有人)
    public enum RenrenAlbumType
    {
        Private = -1,
        Public = 99
    }

    public class Common
    {
        private Common()
        { }

        public static ResponseContent GetUrl(string url, Encoding encoding, CookieCollection cookies, string method, byte[] data, bool uploadFile)
        {
            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
            request.CookieContainer = new CookieContainer();
            if (cookies != null)
            {
                request.CookieContainer.Add(cookies);
            }
            request.Method = method.ToUpper();
            if (data != null)
            {
                if (request.Method == "POST" && uploadFile)
                {
                    request.ContentType = "multipart/form-data; boundary=----------ei4KM7KM7GI3ei4ei4ei4Ef1cH2cH2";
                    
                }
                else
                {
                    request.ContentType = "application/x-www-form-urlencoded";
                }
                request.ContentLength = data.Length;
                Stream stream = request.GetRequestStream();
                stream.Write(data, 0, data.Length);
                stream.Close();
            }
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            System.IO.StreamReader reader = new System.IO.StreamReader(response.GetResponseStream(), encoding);
            string htmlstr = reader.ReadToEnd();

            reader.Close();

            CookieCollection responseCookies = new CookieCollection();
            if (request.CookieContainer != null)
            {
                foreach (Cookie cookie in request.CookieContainer.GetCookies(response.ResponseUri))
                {
                    responseCookies.Add(cookie);
                }
            }
            if (response.Cookies != null)
            {
                foreach (Cookie cookie in response.Cookies)
                {
                    responseCookies.Add(cookie);
                }
            }
            WebHeaderCollection responseHeaders = response.Headers;

            response.Close();
            return new ResponseContent()
            {
                headers = responseHeaders,
                cookies = responseCookies,
                content = htmlstr
            };
        }

        public static ResponseContent GetUrl(string url, Encoding encoding, CookieCollection cookies, string method, string content)
        {
            byte[] data = string.IsNullOrEmpty(content) ? null : encoding.GetBytes(content);
            return GetUrl(url, encoding, cookies, method, data, false);
        }

        public static byte[] GetPhoto(string header, string footer, byte[] fileData)
        {
            

            MemoryStream memStream = new MemoryStream();

            // WebClient client =
            // string FilePath = @"D:\\img_2.jpg";
            // byte[] buffer = new byte[1024];
            // FileStream fs = File.OpenRead( FilePath );
            // int bytesRead;

            byte[] headBytes = Encoding.UTF8.GetBytes(header);
            memStream.Write(headBytes, 0, headBytes.Length);

            memStream.Write(fileData, 0, fileData.Length);

            byte[] footBytes = Encoding.UTF8.GetBytes(footer);
            memStream.Write(footBytes, 0, footBytes.Length);

            memStream.Position = 0;
            byte[] tempBuffer = new byte[memStream.Length];
            memStream.Read(tempBuffer, 0, tempBuffer.Length);
            memStream.Close();

            return tempBuffer;
        }

        public static byte[] GetPhotoContent(string token, string fileName, byte[] fileData)
        {
            string header = @"----------ei4KM7KM7GI3ei4ei4ei4Ef1cH2cH2
Content-Disposition: form-data; name=""status""


----------ei4KM7KM7GI3ei4ei4ei4Ef1cH2cH2
Content-Disposition: form-data; name=""file""; filename=""{0}""
Content-Type: image/jpeg

";
            string footer = string.Format(@"
----------ei4KM7KM7GI3ei4ei4ei4Ef1cH2cH2
Content-Disposition: form-data; name=""requestToken""

{0}
----------ei4KM7KM7GI3ei4ei4ei4Ef1cH2cH2--
", token);

            MemoryStream memStream = new MemoryStream();

            // WebClient client =
            // string FilePath = @"D:\\img_2.jpg";
            // byte[] buffer = new byte[1024];
            // FileStream fs = File.OpenRead( FilePath );
            // int bytesRead;

            byte[] headBytes = Encoding.UTF8.GetBytes(string.Format(header, fileName));
            memStream.Write(headBytes, 0, headBytes.Length);

            memStream.Write(fileData, 0, fileData.Length);

            byte[] footBytes = Encoding.UTF8.GetBytes(footer);
            memStream.Write(footBytes, 0, footBytes.Length);

            memStream.Position = 0;
            byte[] tempBuffer = new byte[memStream.Length];
            memStream.Read(tempBuffer, 0, tempBuffer.Length);
            memStream.Close();

            return tempBuffer;
        }


        public static byte[] GetPhotoContent(string path,string header,string footer)
        {
            

            MemoryStream memStream = new MemoryStream();
            string FilePath = path;
            byte[] buffer = new byte[1024];
            FileStream fs = File.OpenRead(FilePath);
            int bytesRead;

            byte[] headBytes = Encoding.UTF8.GetBytes(header);
            memStream.Write(headBytes, 0, headBytes.Length);
            while ((bytesRead = fs.Read(buffer, 0, buffer.Length)) != 0)
            {
                memStream.Write(buffer, 0, bytesRead);
            }
            byte[] footBytes = Encoding.UTF8.GetBytes(footer);
            memStream.Write(footBytes, 0, footBytes.Length);

            memStream.Position = 0;
            byte[] tempBuffer = new byte[memStream.Length];
            memStream.Read(tempBuffer, 0, tempBuffer.Length);
            memStream.Close();

            return tempBuffer;
        }


    }



    public class ResponseContent
    {
        public CookieCollection cookies;
        public WebHeaderCollection headers;
        public string content;
    }

    public class KaixinEncode
    {
        private long f(long s, long x, long y, long z)
        {
            switch (s)
            {
                case 0:
                    return (x & y) ^ (~x & z);
                    break;
                case 1:
                    return x ^ y ^ z;
                    break;
                case 2:
                    return (x & y) ^ (x & z) ^ (y & z);
                    break;
                case 3:
                    return x ^ y ^ z;
                    break;
            }
            return 0;
        }

        private long rotl(long x, int n)
        {
            return (x << n) | (rm(x, (32 - n)));
        }

        private string tohs(long str)
        {
            StringBuilder s = new StringBuilder();
            long v;
            for (int i = 7; i >= 0; i--)
            {
                v = (rm(str, (i * 4))) & 0xF;
                s.Append(v.ToString("x"));
            }
            return s.ToString();
        }

        private string h(string msg)
        {
            long[] K = new long[] { 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6 };
            msg += ((char)0x80).ToString();
            int l = msg.Length / 4 + 2;
            int N = (int)Math.Ceiling((double)l / 16);
            long[,] M = new long[N, 16];
            for (int i = 0; i < N; i++)
            {
                for (int j = 0; j < 16; j++)
                {
                    M[i, j] = (((msg.Length - 1 >= i * 64 + j * 4 + 0) ? msg[i * 64 + j * 4 + 0] << 24 : 0)) |
                                (((msg.Length - 1 >= i * 64 + j * 4 + 1) ? msg[i * 64 + j * 4 + 1] << 16 : 0)) |
                                (((msg.Length - 1 >= i * 64 + j * 4 + 2) ? msg[i * 64 + j * 4 + 2] << 8 : 0)) |
                                (((msg.Length - 1 >= i * 64 + j * 4 + 3) ? msg[i * 64 + j * 4 + 3] << 0 : 0));
                    //M[i][j] = (msg.charCodeAt(i * 64 + j * 4) << 24) | (msg.charCodeAt(i * 64 + j * 4 + 1) << 16) | (msg.charCodeAt(i * 64 + j * 4 + 2) << 8) | (msg.charCodeAt(i * 64 + j * 4 + 3));					
                }
            }
            M[N - 1, 14] = (long)(((msg.Length - 1) * 8) / Math.Pow(2, 32));
            M[N - 1, 14] = (long)Math.Floor((double)M[N - 1, 14]);
            M[N - 1, 15] = ((msg.Length - 1) * 8) & 0xFFFFFFFF;
            long H0 = 0x67452301;
            long H1 = 0xefcdab89;
            long H2 = 0x98badcfe;
            long H3 = 0x10325476;
            long H4 = 0xc3d2e1f0;
            long[] W = new long[80];
            long a, b, c, d, e;
            for (int i = 0; i < N; i++)
            {
                for (int t = 0; t < 16; t++)
                    W[t] = M[i, t];
                for (int t = 16; t < 80; t++)
                    W[t] = this.rotl(W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16], 1);
                a = H0;
                b = H1;
                c = H2;
                d = H3;
                e = H4;
                for (var t = 0; t < 80; t++)
                {
                    long s = (long)Math.Floor((double)t / 20);
                    long T = (this.rotl(a, 5) + this.f(s, b, c, d) + e + K[s] + W[t]) & 0xFFFFFFFF;
                    e = d;
                    d = c;
                    c = this.rotl(b, 30);
                    b = a;
                    a = T;
                }
                H0 = (H0 + a) & 0xFFFFFFFF;
                H1 = (H1 + b) & 0xFFFFFFFF;
                H2 = (H2 + c) & 0xFFFFFFFF;
                H3 = (H3 + d) & 0xFFFFFFFF;
                H4 = (H4 + e) & 0xFFFFFFFF;
            }
            return this.tohs(H0) + this.tohs(H1) + this.tohs(H2) + this.tohs(H3) + this.tohs(H4);
        }

        private string bh(Dictionary<int, long> ar)
        {
            string charHex = "0123456789abcdef";
            StringBuilder sb = new StringBuilder();
            int len = ar.Count;
            for (int i = 0, tmp = len << 2; i < tmp; i++)
            {
                sb.Append(charHex[(int)((ar[i >> 2] >> (((i & 3) << 3) + 4)) & 0xF)]);
                sb.Append(charHex[(int)((ar[i >> 2] >> ((i & 3) << 3)) & 0xF)]);
            }
            return sb.ToString();
        }

        private Dictionary<int, long> sl(string s, bool w)
        {
            int len = s.Length;
            Dictionary<int, long> v = new Dictionary<int, long>();
            for (int i = 0; i < len; i += 4)
            {
                v[i >> 2] = s[i] |
                            ((s.Length - 1 >= i + 1) ? s[i + 1] : 0) << 8 |
                            ((s.Length - 1 >= i + 2) ? s[i + 2] : 0) << 16 |
                            ((s.Length - 1 >= i + 3) ? s[i + 3] : 0) << 24;
                //v[i >> 2] = s.charCodeAt(i) | s.charCodeAt(i + 1) << 8 | s.charCodeAt(i + 2) << 16 | s.charCodeAt(i + 3) << 24;
            }
            if (w)
            {
                v[v.Count] = len;
            }
            return v;
        }

        private string en(string str, string key)
        {
            if (string.IsNullOrEmpty(str))
            {
                return "";
            }
            Dictionary<int, long> v = this.sl(str, true);
            Dictionary<int, long> k = this.sl(key, false);
            //if (k.Count < 4)
            //{
            //    k.Count = 4;
            //}
            int n = v.Count - 1;
            long z = v[n];
            long y = v[0];
            long de = 2654435769;
            long mx;
            int e;
            int p;
            int q = (int)Math.Floor((6 + (double)52 / (n + 1)));
            long sum = 0;
            while (0 < q--)
            {
                sum = sum + de & 0xFFFFFFFF;
                e = (int)(rm(sum, 2) & 3);
                for (p = 0; p < n; p++)
                {
                    y = v[p + 1];
                    mx = (rm(z, 5) ^ y << 2) + (rm(y, 3) ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z);
                    z = v[p] = v[p] + mx & 0xFFFFFFFF;
                }
                y = v[0];
                mx = (rm(z, 5) ^ y << 2) + (rm(y, 3) ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z);
                z = v[n] = v[n] + mx & 0xFFFFFFFF;
            }
            return this.bh(v);
        }

        private long rm(long num, int m)
        {
            return m > 0 ? num >> m & ((1 << (32 - m)) - 1) : num;
        }

        private string uen(string str)
        {
            StringBuilder sb = new StringBuilder();
            foreach (var i in str)
            {
                string iStr = HttpUtility.UrlEncode(i.ToString());
                if (iStr.Length > 1)
                {
                    sb.Append(iStr.ToUpper());
                }
                else
                {
                    sb.Append(i);
                }
            }
            return sb.ToString();
            //return encodeURIComponent(str).replace(/!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28').replace(/\)/g, '%29').replace(/\*/g, '%2A').replace(/%20/g, '+').replace(/~/g, '%7E');
        }

        public string enp(string p, string key)
        {
            return this.h(this.en(this.uen(p), key));
        }
    }
    public class GetClientIP
    {
        public static string GetClientIp()
        {
            try
            {
                if (HttpContext.Current == null
                    || HttpContext.Current.Request == null
                    || HttpContext.Current.Request.ServerVariables == null)
                    return "";

                string CustomerIP = "";

                //CDN加速后取到的IP
                CustomerIP = HttpContext.Current.Request.Headers["Cdn-Src-Ip"];
                if (!string.IsNullOrEmpty(CustomerIP))
                {
                    return CustomerIP;
                }

                if (HttpContext.Current.Request.ServerVariables["HTTP_VIA"] != null)
                {
                    CustomerIP = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
                    if (CustomerIP == null)
                        CustomerIP = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
                }
                else
                {
                    CustomerIP = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
                }

                if (string.Compare(CustomerIP, "unknown", true) == 0)
                    return HttpContext.Current.Request.UserHostAddress;
                return CustomerIP;
               
            }
            catch
            {
                return "";
            }
        }
    }

    public class xmlHelper
    {
        private XmlDocument doc;
        public xmlHelper(string xml)
        {
            doc = new XmlDocument();
            doc.LoadXml(xml);
        }

        public string getValue(string xpath)
        {
            XmlNode node = doc.SelectSingleNode(xpath);
            if (node != null)
                return node.ChildNodes.Count > 0 ? node.ChildNodes[0].Value : "";
            else
                return null;
           
        }
    }

    public class Des
    {
        #region 加密

        private const string KEY_64 = "BF23.SDG"; //8个字符，64位


        private const string IV_64 = "BF23.SDG";

        private Des()
        { }

        /// <summary>
        /// DES加密
        /// </summary>
        /// <param name="data">待加密的数据</param>
        /// <returns>加密后的数据</returns>
        public static string DesEncrypt(string data)
        {
            try
            {
                byte[] byKey = System.Text.ASCIIEncoding.ASCII.GetBytes(KEY_64);
                byte[] byIV = System.Text.ASCIIEncoding.ASCII.GetBytes(IV_64);

                DESCryptoServiceProvider cryptoProvider = new DESCryptoServiceProvider();
                int i = cryptoProvider.KeySize;
                MemoryStream ms = new MemoryStream();
                CryptoStream cst = new CryptoStream(ms, cryptoProvider.CreateEncryptor(byKey, byIV), CryptoStreamMode.Write);

                StreamWriter sw = new StreamWriter(cst);
                sw.Write(data);
                sw.Flush();
                cst.FlushFinalBlock();
                sw.Flush();

                string str64 = Convert.ToBase64String(ms.GetBuffer(), 0, (int)ms.Length);
                return str64.Replace("+", "{plus}").Replace("/", "{line}").Replace("=", "{equel}");
            }
            catch
            {
                return data;
            }

        }
        #endregion

        #region 解密

        public static string DESDecrypt(string str)
        {
            byte[] byKey = System.Text.ASCIIEncoding.ASCII.GetBytes(KEY_64);
            byte[] byIV = System.Text.ASCIIEncoding.ASCII.GetBytes(IV_64);
            string res = "";
            if (string.IsNullOrEmpty(str))
            {
                return str;
            }
            str = str.Replace("{plus}", "+").Replace("{line}", "/").Replace("{equel}", "=");
            //int d = str.Length;
            if (str != "")
            {
                DESCryptoServiceProvider cp = new DESCryptoServiceProvider();
                byte[] buffer = { };
                try
                {
                    buffer = Convert.FromBase64String(str);
                }
                catch (Exception ex)
                {
                    res = ex.Message;
                }
                MemoryStream ms = new MemoryStream(buffer);
                CryptoStream cs = new CryptoStream(ms, cp.CreateDecryptor(byKey, byIV), CryptoStreamMode.Read);
                StreamReader sr = new StreamReader(cs);

                res = sr.ReadToEnd();
            }
            return res;

        }
        #endregion
    }




}
